home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
-
- Probable Worlds
-
- Copyright 1997 (c) Complex
-
- Design and Programming by Jarno Heikkinen (jarnoh@yomimedia.fi)
-
- ****************************************************************************/
-
- #include "stdafx.h"
- #include <stdlib.h>
- #include <stdio.h>
- #include <windows.h>
-
- #include "saver.h"
- #include "test.h"
-
- #pragma warning( once : 4305 4244 )
- #include "klunssi.h"
-
- extern TCHAR szConfig[]; //=_T("Config");
-
- // quick macro to scale 32bit ABGR color (uses fadetab scaling table)
- #define FADE(q) (fadetab[q&0xff]|(fadetab[(q&0xff00)>>8]<<8)|(fadetab[(q&0xff0000)>>16]<<16))
-
- // different fog colors
- FxU32 fogColors[]={
- 0xc0c0c0c0,
- 0x00000000,
- 0x00302000,
- 0x00307070,
- 0x00804020,
- 0x001050e0,
- 0x00405050,
- 0x00c01060,
- 0x0000d0d0,
- 0x00ff0040,
- 0x000040ff
- };
-
-
- /****************************************************************************/
-
- Probe::Probe()
- {
- GrHwConfiguration hwconfig;
-
- #ifndef NOMUSIC
- MIDASstartup();
- #endif
-
- // Initialize Glide
- grGlideInit();
- grSstQueryHardware( &hwconfig );
- grSstSelect( 0 );
-
- frames=-1;
- kala=0;
- initok=0;
- }
-
- /****************************************************************************/
- void Probe::prepare()
- {
- int i;
- float asdf=0.;
-
- // load texture data from resources
- // 666 is our resource ID
- HRSRC hRes;
- hRes = FindResource(NULL, "#666", "texture");
-
- if(hRes)
- {
- bmpsize=SizeofResource(NULL, hRes);
- bmp=new FxU8[bmpsize];
- memcpy(bmp, LockResource(LoadResource(NULL, hRes)), bmpsize);
- }
- else
- {
- bmp=NULL;
- bmpsize=0;
- // MessageBox(NULL, "perkele", "", MB_OK);
- }
-
- // FreeResource(hRes);
-
- srand( GetTickCount() );
-
- // scale the object and calculate normals...
- objvertAm=sizeof(objvert)/sizeof(objvert[0])/3;
- objfaceAm=sizeof(objface)/sizeof(objface[0])/3;
-
- rotvert=new GrVertex[objvertAm];
- objvn=new Vector3[objvertAm];
-
- memset(rotvert, 0, sizeof(GrVertex)*objvertAm);
- memset(objvn, 0, sizeof(Vector3)*objvertAm);
-
- for(i=0;i<objvertAm*3;i++) if(objvert[i] > asdf) asdf=objvert[i];
- for(i=0;i<objvertAm*3;i++) objvert[i]=objvert[i]*(1.f/asdf);
-
- objfn=new Vector3[objfaceAm];
- for(i=0; i<objfaceAm; i++)
- {
- Vector3 tn;
- Vector3 a=Vector3(&objvert[3*objface[i*3]]);
- Vector3 b=Vector3(&objvert[3*objface[i*3+1]]);
- Vector3 c=Vector3(&objvert[3*objface[i*3+2]]);
- tn.x= (b.y-a.y)*(c.z-a.z)-(c.y-a.y)*(b.z-a.z);
- tn.y=-((b.x-a.x)*(c.z-a.z)-(c.x-a.x)*(b.z-a.z));
- tn.z= (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
- objfn[i]=tn.normalize();
- }
-
- for(i=0; i<objfaceAm*3; i++) objvn[objface[i]] += objfn[i/3];
- for(i=0; i<objvertAm; i++) objvn[i]=objvn[i].normalize();
-
- // then some glide preparations...
- if(!grSstWinOpen( (unsigned long)AfxGetMainWnd()->m_hWnd, GR_RESOLUTION_640x480, GR_REFRESH_60Hz,
- GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1 ))
- {
- MessageBox(NULL, "failed", "", MB_OK);
- return;
- };
-
- float sw=(float)grSstScreenWidth();
- float sh=(float)grSstScreenHeight();
-
- texVerts[0].x = 0.f; texVerts[0].y = sh;
- texVerts[1].x = sw; texVerts[1].y = sh;
- texVerts[2].x = sw; texVerts[2].y = 0.f;
- texVerts[3].x = 0.f; texVerts[3].y = 0.f;
- texVerts[0].oow=texVerts[1].oow=0.29f;
- texVerts[2].oow=texVerts[3].oow=0.29f/24;
-
- // allocate space for texture (3dfx)
- envMap = guTexAllocateMemory( 0, GR_MIPMAPLEVELMASK_BOTH, 256, 256,
- GR_TEXFMT_P_8, GR_MIPMAP_NEAREST, GR_LOD_256, GR_LOD_256,
- GR_ASPECT_1x1, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP,
- GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR, 0.0F, FXFALSE );
-
- texMap = guTexAllocateMemory( 0, GR_MIPMAPLEVELMASK_BOTH, 128, 128,
- GR_TEXFMT_P_8, GR_MIPMAP_NEAREST, GR_LOD_128, GR_LOD_128,
- GR_ASPECT_1x1, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP,
- GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR, 0.0F, FXFALSE );
-
- // first texture is the envmap...
- for(i=0;i<256;i++) envPal.data[i]=(bmp[i*3+32]<<16)+(bmp[i*3+1+32]<<8)+(bmp[i*3+2+32])&0xffffff;
- guTexDownloadMipMap( envMap, bmp+800, NULL );
-
- memset(&texPal, 0, sizeof(texPal));
-
- for( i = 0; i < objvertAm; i++ ) rotvert[i].oow=1.f;
-
- grDepthMask(1);
- grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
- grDepthBufferFunction(GR_CMP_LESS);
-
- grDitherMode(GR_DITHER_DISABLE);
- grCullMode(GR_CULL_POSITIVE);
-
- // default to solid screen write (full alpha -> no blur!)
- grConstantColorValue(~0);
-
- grAlphaCombine(
- GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
- GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE,FXFALSE );
- grColorCombine(
- GR_COMBINE_FUNCTION_SCALE_OTHER,
- GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE,
- GR_COMBINE_OTHER_TEXTURE, FXFALSE);
- grTexCombine(GR_TMU0,
- GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
- GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,FXFALSE, FXFALSE);
-
- // generate fog table
- guFogGenerateExp( fogtable, .05f );
- grFogTable( fogtable );
- grFogMode( GR_FOG_WITH_TABLE );
-
- // save default rendering state
- grGlideGetState(&defState);
-
- // ========================================================================================
- // setup background rendering state
- grGlideSetState(&defState);
- grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA,
- GR_BLEND_ZERO, GR_BLEND_ZERO );
- guTexSource(texMap);
-
- // always write pixels + depth
- // (background is full always so it does the clearing too :)
- grDepthBufferFunction(GR_CMP_ALWAYS);
- grGlideGetState(&bgState); // save to bgState
- // ========================================================================================
- // setup klunssi object rendering state
- grGlideSetState(&defState);
- grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO);
- guTexSource(envMap);
- grFogMode( GR_FOG_DISABLE );
- grGlideGetState(&klunssiState);
- // ========================================================================================
-
- #ifndef NOMUSIC
-
- /* Initialize MIDAS and start background playback: */
- module=NULL;
- if( (AfxGetApp()->GetProfileInt(szConfig, _T("Mute"), 0)==0) && MIDASinit())
- {
- if(MIDASstartBackgroundPlay(100))
- {
- /* Load the module and start playing: */
- // module = MIDASloadModule("d:\\projects\\glidetest\\trans.xm");
- LPCTSTR name = AfxGetApp()->GetProfileString(szConfig, _T("FileName"), "");
- module = MIDASloadModule((char*)name);
- if(module) MIDASplayModule(module, 0);
- }
- }
- #endif
-
- // run at idle priority...
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);
- initok=1;
- }
-
- /****************************************************************************/
- // randomize rotation and fog color
- void Probe::randomScene()
- {
- if(!initok) this->prepare();
-
- float rd=1.f/(float)RAND_MAX;
- cameraRotate=(rand()*rd-.5f)*.015f;
- cameraSpeed=(rand()*rd-.5f)*2.24f;
- rotSpeed=Vector3(rand()*rd-.5f, rand()*rd-.5f, rand()*rd-.5f)*4.f;
-
- fogColor = fogColors[ rand() % (sizeof(fogColors)/sizeof(fogColors[0])) ];
-
- // get new texture .. there's 15 128x128 textures and 256x256 texture for envmap
- FxU8 *pic=bmp+(rand()%15)*17184+66336;
-
- // download texture
- guTexDownloadMipMap( texMap, pic+800, NULL );
- // copy palette
- for(int i=0;i<256;i++) texPal.data[i]=(pic[32+i*3]<<16)+(pic[32+i*3+1]<<8)+(pic[32+i*3+2])&0xffffff;
-
- // generate fog table
- guFogGenerateExp( fogtable, .0035f + ((rand()%100)*.001f) );
- grFogTable( fogtable );
-
- // random blur amount
- blurAm = rand()%192+64;
- }
-
- /****************************************************************************/
- void Probe::run()
- {
- int i, j;
- if(!initok)
- {
- this->prepare();
- return;
- }
-
- if(frames<0)
- {
- timeold=GetTickCount();
- kala=0;
- frames=0;
- randomScene();
- }
-
- float t=(GetTickCount()-timeold)*0.04f;
-
- j=frames;
- if(j<0) j=0;
- if(j>256) j=256;
-
- for(i=0;i<256;i++) fadetab[i]=(i*j)>>8;
-
- if(kala==0) frames+=1;
- if(kala==1) frames-=3;
-
- if(frames>700) kala=1;
-
- Vector3 v=rotSpeed * (t*60.f*.00015f);
-
- // rotation matrix
- Vector3 m0, m1, m2;
- m0.x = (float)(cos(v.y) * cos(v.z) - sin(v.y) * sin(v.x) * sin(v.z));
- m0.y = (float)(-cos(v.x) * sin(v.z));
- m0.z = (float)(sin(v.y) * cos(v.z) + cos(v.y) * sin(v.x) * sin(v.z));
- m1.x = (float)(cos(v.y) * sin(v.z) + sin(v.y) * sin(v.x) * cos(v.z));
- m1.y = (float)(cos(v.x) * cos(v.z));
- m1.z = (float)(sin(v.y) * sin(v.z) - cos(v.y) * sin(v.x) * cos(v.z));
- m2.x = (float)(-sin(v.y) * cos(v.x));
- m2.y = (float)(sin(v.x));
- m2.z = (float)(cos(v.y) * cos(v.x));
-
- // screen center + magic snapping constant
- // remove the snap and glide hangs nicely :)
- float sw=(float)grSstScreenWidth();
- float sh=(float)grSstScreenHeight();
- float hw=sw*.5f+((float)( 3 << 18 ));
- float hh=sh*.5f+((float)( 3 << 18 ));
-
- sh *= 1.2f; // aspect ratio fix
-
- for( i = 0; i < objvertAm; i++ )
- {
- // add pivot
- Vector3 q=Vector3(objvert[i*3]+.8f, objvert[i*3+1], objvert[i*3+2]);
-
- v.x=m0.x*q.x+m0.y*q.y+m0.z*q.z;
- v.y=m1.x*q.x+m1.y*q.y+m1.z*q.z;
- v.z=m2.x*q.x+m2.y*q.y+m2.z*q.z+2.5f; // + zdistance
-
- if(v.z<1.f) v.z=1.f;
-
- float ow=1.f/v.z;
-
- rotvert[i].oow=ow;
-
- v.x=v.x*sw*ow;
- v.y=v.y*sh*ow;
-
- rotvert[i].x = v.x+hw;
- rotvert[i].y = v.y+hh;
-
- // rotate vertex normals
- v.x=m0.x*objvn[i].x+m0.y*objvn[i].y+m0.z*objvn[i].z;
- v.y=m1.x*objvn[i].x+m1.y*objvn[i].y+m1.z*objvn[i].z;
-
- // use them for envmap
- rotvert[i].tmuvtx[0].sow = (1-v.x)*128.f*rotvert[i].oow;
- rotvert[i].tmuvtx[0].tow = (1-v.y)*128.f*rotvert[i].oow;
- }
-
- float ang=(float)t*cameraRotate;
- float pos=t*cameraSpeed;
- for(i=0;i<4;i++)
- {
- // this looks good enough :)
- texVerts[i].tmuvtx[0].sow = (float)sin(ang)*13.f;
- texVerts[i].tmuvtx[0].tow = (float)cos(ang)*13.f+pos*texVerts[i].oow;
- ang+=2*3.1415/4;
- }
-
- grGlideSetState(&bgState);
- grFogColorValue( FADE(fogColor) );
- for(i=0;i<256;i++) realPal.data[i]=FADE(texPal.data[i]);
- grTexDownloadTable(GR_TMU0, GR_TEXTABLE_PALETTE, &realPal);
-
- // "motion blur" (for very dark fade phase we use solid (default))
- if(frames>2) grConstantColorValue( blurAm<<24 );
-
- // draw the background
- grDrawTriangle(&texVerts[0], &texVerts[1], &texVerts[2]);
- grDrawTriangle(&texVerts[2], &texVerts[3], &texVerts[0]);
-
- grGlideSetState(&klunssiState);
-
- for(i=0;i<256;i++) realPal.data[i]=FADE(envPal.data[i]);
- grTexDownloadTable(GR_TMU0, GR_TEXTABLE_PALETTE, &realPal);
-
- // no clipping because we dont really draw that much polygons
- // and we fit into 3dfx "secure" area (+-1024 i think? :)
- for( i = 0; i < objfaceAm; i++ )
- {
- grDrawTriangle(
- rotvert+objface[i*3+0],
- rotvert+objface[i*3+1],
- rotvert+objface[i*3+2]);
- }
- framesTotal++;
-
- grSstIdle();
- grBufferSwap(1);
- }
-
- /****************************************************************************/
-
- Probe::~Probe()
- {
- grGlideShutdown();
-
- #ifndef NOMUSIC
- // Stop playing and deallocate module:
- if(module) MIDASstopModule(module);
- if(module) MIDASfreeModule(module);
-
- module=NULL;
-
- // Stop background playback and uninitialize MIDAS:
- MIDASstopBackgroundPlay();
- MIDASclose();
- #endif
-
- return;
- }
-
-